/**
 * Copyright 1998-2006, CHISEL Group, University of Victoria, Victoria, BC, Canada.
 * All rights reserved.
 */
package ca.uvic.cs.cogz.mapping.filter;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;

import ca.uvic.cs.cogz.mapping.core.AbstractMapElement;
import ca.uvic.cs.cogz.mapping.filter.TreeFilterManager.TreeFilterType;
import ca.uvic.cs.cogz.util.TreeUtil;
import edu.stanford.smi.protege.model.Cls;
import edu.stanford.smi.protege.model.Frame;
import edu.stanford.smi.protege.model.KnowledgeBase;

/**
 * Implementation of a ITreeSearchBasedFilter. Used for filtering a tree to show only the part of
 * the hierarchy necessary to display candidate/mapped items to the currently select tree item.
 * 
 * @author Sean Falconer
 * @date 14-March-08
 */
public class FrameToMappingsItemFilter implements ITreeSearchBasedFilter {
	private int treeIndex;
	private HashSet<Cls> searchResults;
	private List<AbstractMapElement> mappings;

	public FrameToMappingsItemFilter() {
		searchResults = new HashSet<Cls>();
	}

	public void setTreeIndex(int treeIndex) {
		this.treeIndex = treeIndex;
	}

	public void setMappings(List<AbstractMapElement> mappings) {
		this.mappings = mappings;
	}

	@SuppressWarnings("unchecked")
	public Collection<Collection> performSearch(KnowledgeBase kb) {
		searchResults.clear();

		boolean isSource = (treeIndex == TreeFilterManager.SOURCE_SEARCH);
		HashSet<Collection> matchedPaths = new HashSet<Collection>(mappings.size());

		for (AbstractMapElement searchHit : mappings) {
			Cls clsItem = (Cls) ((isSource) ? searchHit.getSourceFrame() : searchHit.getTargetFrame());

			searchResults.add(clsItem);
			searchResults.addAll(clsItem.getSuperclasses());

			ArrayList<Frame> currentPath = new ArrayList<Frame>();
			TreeUtil.buildObjectPaths(clsItem, currentPath, matchedPaths, true);
		}

		return matchedPaths;
	}

	/**
	 * Checks to see if any of the search results match the given frame.
	 */
	public boolean isMatch(Frame frame) {
		return isActive() && searchResults.contains(frame);
	}

	public boolean isActive() {
		return searchResults.size() > 0;
	}

	public void reset() {
		searchResults.clear();
	}

	public TreeFilterType getType() {
		return TreeFilterType.FRAME_TO_MAPPINGS_FILTER;
	}
}
